/**
 * 管理端认证状态管理
 */
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import type { AdminInfo, LoginParams, SocialBindParams, SocialLoginParams, WeixinMiniAppLoginParams } from '@/api/auth'
import { adminLogin, logout as apiLogout, refreshToken as apiRefreshToken, socialLogin as apiSocialLogin, bindSocialAccount, getAdminInfo, getTenantIdByName, weixinMiniAppLogin as weixinMiniAppLoginApi } from '@/api/auth'
import platformConfig from '@/utils/platform'

export const useAuthStore = defineStore('auth', () => {
  // 状态
  const token = ref<string>('')
  const refreshToken = ref<string>('')
  const expiresTime = ref<string>('')
  const tenantId = ref<number | string>(0) // 租户ID
  const admin = ref<AdminInfo | null>(null)
  const isLoggedIn = ref<boolean>(false)

  // 计算属性
  const isAuthenticated = computed(() => isLoggedIn.value && !!token.value)
  const adminInfo = computed(() => admin.value)
  const adminNickname = computed(() => admin.value?.nickname || '管理员')
  const adminAvatar = computed(() => admin.value?.avatar || '')
  const adminRoles = computed(() => admin.value?.roleNames || [])
  const adminPosts = computed(() => admin.value?.postNames || [])

  const isTokenExpiringSoon = computed(() => {
    if (!expiresTime.value)
      return false
    const expTime = new Date(expiresTime.value).getTime()
    const now = Date.now()
    const thirtyMinutes = 30 * 60 * 1000
    return expTime - now < thirtyMinutes
  })

  const isTokenExpired = computed(() => {
    if (!expiresTime.value)
      return false
    const expTime = new Date(expiresTime.value).getTime()
    return Date.now() > expTime
  })

  // Token状态监控
  const tokenStatus = computed(() => ({
    isLoggedIn: isLoggedIn.value,
    hasToken: !!token.value,
    tokenLength: token.value?.length || 0,
    isExpired: isTokenExpired.value,
    isExpiringSoon: isTokenExpiringSoon.value,
    expiresTime: expiresTime.value,
    timeUntilExpiry: expiresTime.value ? new Date(expiresTime.value).getTime() - Date.now() : 0,
  }))

  // 方法
  async function login(params: LoginParams) {
    try {
      const response = await adminLogin(params)

      if (response.code === 0 && response.data) {
        const loginData = response.data

        // 保存Token信息
        token.value = loginData.accessToken
        refreshToken.value = loginData.refreshToken
        expiresTime.value = loginData.expiresTime
        tenantId.value = loginData.tenantId || 0
        isLoggedIn.value = true

        // 保存到本地存储
        uni.setStorageSync('admin-token', loginData.accessToken)
        uni.setStorageSync('admin-refresh-token', loginData.refreshToken)
        uni.setStorageSync('admin-expires-time', loginData.expiresTime)
        uni.setStorageSync('admin-tenant-id', loginData.tenantId || 0)

        // 获取管理员信息
        await fetchAdminInfo()

        return loginData
      }
      else {
        throw new Error(response.msg || '登录失败')
      }
    }
    catch (error: any) {
      console.error('登录失败:', error)
      throw error
    }
  }

  async function fetchAdminInfo() {
    try {
      const response = await getAdminInfo()

      if (response.code === 0 && response.data) {
        admin.value = response.data
        return response.data
      }
      else {
        throw new Error(response.msg || '获取管理员信息失败')
      }
    }
    catch (error: any) {
      console.error('获取管理员信息失败:', error)
      throw error
    }
  }

  async function refreshAccessToken() {
    try {
      if (!refreshToken.value) {
        throw new Error('无有效的刷新Token')
      }

      const response = await apiRefreshToken(refreshToken.value)

      if (response.code === 0 && response.data) {
        const loginData = response.data

        // 更新Token信息
        token.value = loginData.accessToken
        refreshToken.value = loginData.refreshToken
        expiresTime.value = loginData.expiresTime
        tenantId.value = loginData.tenantId || 0

        // 更新本地存储
        uni.setStorageSync('admin-token', loginData.accessToken)
        uni.setStorageSync('admin-refresh-token', loginData.refreshToken)
        uni.setStorageSync('admin-expires-time', loginData.expiresTime)
        uni.setStorageSync('admin-tenant-id', loginData.tenantId || 0)

        return loginData
      }
      else {
        throw new Error(response.msg || '刷新Token失败')
      }
    }
    catch (error: any) {
      console.error('刷新Token失败:', error)
      // 刷新失败则清除认证信息
      clearAuth()
      throw error
    }
  }

  async function logout() {
    try {
      // 调用退出登录接口
      if (token.value) {
        await apiLogout()
      }
    }
    catch (error) {
      console.error('退出登录接口调用失败:', error)
      // 即使接口调用失败，也要清除本地认证信息
    }
    finally {
      // 清除认证信息
      clearAuth()

      // 跳转到登录页
      console.log('🚪 管理员退出登录，跳转到登录页')
      uni.reLaunch({
        url: '/pages/auth/login',
      })
    }
  }

  function setAuthData(data: {
    token: string
    refreshToken: string
    expiresTime: string
    tenantId?: number | string
    admin?: AdminInfo
  }) {
    token.value = data.token
    refreshToken.value = data.refreshToken
    expiresTime.value = data.expiresTime
    tenantId.value = data.tenantId || 0
    if (data.admin) {
      admin.value = data.admin
    }
    isLoggedIn.value = true

    // 保存到本地存储
    uni.setStorageSync('admin-token', data.token)
    uni.setStorageSync('admin-refresh-token', data.refreshToken)
    uni.setStorageSync('admin-expires-time', data.expiresTime)
    uni.setStorageSync('admin-tenant-id', data.tenantId || 0)
  }

  function clearAuth() {
    token.value = ''
    refreshToken.value = ''
    expiresTime.value = ''
    tenantId.value = 0
    admin.value = null
    isLoggedIn.value = false

    // 清除本地存储
    uni.removeStorageSync('admin-token')
    uni.removeStorageSync('admin-refresh-token')
    uni.removeStorageSync('admin-expires-time')
    uni.removeStorageSync('admin-tenant-id')
  }

  function updateAdminInfo(adminInfo: Partial<AdminInfo>) {
    if (admin.value) {
      admin.value = { ...admin.value, ...adminInfo }
    }
  }

  // 设置租户ID
  function setTenantId(newTenantId: number | string) {
    tenantId.value = newTenantId
    uni.setStorageSync('admin-tenant-id', newTenantId)
  }

  async function checkAndRefreshToken() {
    console.log('🔍 检查Token状态:', {
      isLoggedIn: isLoggedIn.value,
      hasToken: !!token.value,
      tokenExpired: isTokenExpired.value,
      tokenExpiringSoon: isTokenExpiringSoon.value,
      expiresTime: expiresTime.value,
    })

    if (!isLoggedIn.value || !token.value) {
      console.log('❌ 未登录或无Token')
      return false
    }

    // 如果Token已过期，尝试刷新
    if (isTokenExpired.value) {
      console.log('⚠️ Token已过期，尝试刷新')
      try {
        await refreshAccessToken()
        console.log('✅ Token刷新成功')
        return true
      }
      catch (error) {
        console.error('❌ Token刷新失败:', error)
        return false
      }
    }

    // 如果Token即将过期，提前刷新
    if (isTokenExpiringSoon.value) {
      console.log('🔄 Token即将过期，提前刷新')
      try {
        await refreshAccessToken()
        console.log('✅ Token提前刷新成功')
      }
      catch (error) {
        console.warn('⚠️ 提前刷新Token失败:', error)
        // 提前刷新失败不影响当前使用
      }
    }

    console.log('✅ Token状态正常')
    return true
  }

  // 社交登录
  async function socialLogin(params: SocialLoginParams) {
    try {
      const response = await apiSocialLogin(params)

      if (response.code === 0 && response.data) {
        const loginData = response.data

        // 保存Token信息
        token.value = loginData.accessToken
        refreshToken.value = loginData.refreshToken
        expiresTime.value = loginData.expiresTime
        tenantId.value = loginData.tenantId || 0
        isLoggedIn.value = true

        // 更新本地存储
        uni.setStorageSync('admin-token', loginData.accessToken)
        uni.setStorageSync('admin-refresh-token', loginData.refreshToken)
        uni.setStorageSync('admin-expires-time', loginData.expiresTime)
        uni.setStorageSync('admin-tenant-id', loginData.tenantId || 0)

        // 获取管理员信息
        await fetchAdminInfo()

        return loginData
      }
      else {
        throw new Error(response.msg || '社交登录失败')
      }
    }
    catch (error: any) {
      console.error('社交登录失败:', error)
      throw error
    }
  }

  // 绑定社交账号
  async function bindSocial(params: SocialBindParams) {
    try {
      const response = await bindSocialAccount(params)

      if (response.code === 0 && response.data) {
        const loginData = response.data

        // 保存Token信息
        token.value = loginData.accessToken
        refreshToken.value = loginData.refreshToken
        expiresTime.value = loginData.expiresTime
        tenantId.value = loginData.tenantId || 0
        isLoggedIn.value = true

        // 更新本地存储
        uni.setStorageSync('admin-token', loginData.accessToken)
        uni.setStorageSync('admin-refresh-token', loginData.refreshToken)
        uni.setStorageSync('admin-expires-time', loginData.expiresTime)
        uni.setStorageSync('admin-tenant-id', loginData.tenantId || 0)

        // 获取管理员信息
        await fetchAdminInfo()

        return loginData
      }
      else {
        throw new Error(response.msg || '社交账号绑定失败')
      }
    }
    catch (error: any) {
      console.error('社交账号绑定失败:', error)
      throw error
    }
  }

  // 微信小程序一键登录
  async function weixinMiniAppLogin(params: WeixinMiniAppLoginParams) {
    try {
      const response = await weixinMiniAppLoginApi(params)

      if (response.code === 0 && response.data) {
        const loginData = response.data

        // 保存当前的租户ID，避免被后端响应覆盖
        const currentTenantId = tenantId.value

        // 保存Token信息
        token.value = loginData.accessToken
        refreshToken.value = loginData.refreshToken
        expiresTime.value = loginData.expiresTime
        // 保持当前设置的租户ID，如果后端返回了租户ID则使用后端的
        tenantId.value = loginData.tenantId || currentTenantId || 0
        isLoggedIn.value = true

        // 保存openid（如果有）
        if (loginData.openid) {
          uni.setStorageSync('wechat-openid', loginData.openid)
        }

        // 更新本地存储
        uni.setStorageSync('admin-token', loginData.accessToken)
        uni.setStorageSync('admin-refresh-token', loginData.refreshToken)
        uni.setStorageSync('admin-expires-time', loginData.expiresTime)
        uni.setStorageSync('admin-tenant-id', loginData.tenantId || currentTenantId || 0)

        // 获取管理员信息
        await fetchAdminInfo()

        return loginData
      }
      else {
        throw new Error(response.msg || '微信小程序登录失败')
      }
    }
    catch (error: any) {
      console.error('微信小程序登录失败:', error)
      throw error
    }
  }

  // 微信小程序静默登录
  async function wechatSilentLogin(tenantName?: string) {
    try {
      if (!platformConfig.isWechatMiniProgram()) {
        throw new Error('当前不是微信小程序环境')
      }

      // 如果提供了租户名，先获取租户ID
      if (tenantName) {
        try {
          const res = await getTenantIdByName(tenantName)
          if (res.code === 0 && res.data) {
            setTenantId(res.data)
            console.log('✅ 社交登录前获取租户ID成功:', res.data)
          }
        }
        catch (error) {
          console.error('❌ 社交登录前获取租户ID失败:', error)
          throw new Error('获取租户信息失败')
        }
      }

      // 确保有租户ID
      if (!tenantId.value) {
        throw new Error('租户ID未设置，无法进行社交登录')
      }

      const wechatMP = platformConfig.getWechatMiniProgram()
      const loginResult = await wechatMP.silentLogin()

      if (!loginResult.success || !loginResult.code) {
        throw new Error('获取微信授权码失败')
      }

      const params: SocialLoginParams = {
        type: wechatMP.socialType,
        code: loginResult.code,
        state: 'admin-login',
      }

      console.log('🔐 社交登录参数:', params, '租户ID:', tenantId.value)

      try {
        return await socialLogin(params)
      }
      catch (error: any) {
        // 如果是未绑定账号的错误，返回特殊状态
        if (error.message?.includes('未绑定账号') || error.message?.includes('需要进行绑定')) {
          // 抛出包含社交登录参数的特殊错误，供页面处理
          const bindError = new Error('NEED_BIND_ACCOUNT')
          ;(bindError as any).socialParams = params
          throw bindError
        }
        throw error
      }
    }
    catch (error: any) {
      console.error('微信静默登录失败:', error)
      throw error
    }
  }

  // 初始化认证状态
  function initAuth() {
    // 从本地存储恢复认证状态
    const storedToken = uni.getStorageSync('admin-token')
    const storedRefreshToken = uni.getStorageSync('admin-refresh-token')
    const storedExpiresTime = uni.getStorageSync('admin-expires-time')
    const storedTenantId = uni.getStorageSync('admin-tenant-id')

    if (storedToken && storedRefreshToken && storedExpiresTime) {
      token.value = storedToken
      refreshToken.value = storedRefreshToken
      expiresTime.value = storedExpiresTime
      tenantId.value = storedTenantId || 0
      isLoggedIn.value = true

      console.log('🔄 从本地存储恢复认证状态')
    }
  }

  return {
    // 状态
    token,
    refreshToken,
    expiresTime,
    tenantId,
    admin,
    isLoggedIn,

    // 计算属性
    isAuthenticated,
    adminInfo,
    adminNickname,
    adminAvatar,
    adminRoles,
    adminPosts,
    isTokenExpiringSoon,
    isTokenExpired,
    tokenStatus,

    // 方法
    login,
    socialLogin,
    bindSocial,
    weixinMiniAppLogin,
    wechatSilentLogin,
    fetchAdminInfo,
    refreshAccessToken,
    logout,
    setAuthData,
    clearAuth,
    updateAdminInfo,
    setTenantId,
    checkAndRefreshToken,
    initAuth,
  }
}, {
  persist: {
    key: 'admin-auth-store',
  },
})
